You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

49 lines
1.8 KiB

import { z } from "zod";
import { validate } from "#server/utils/validation";
import { updateArticle, getArticleById, ArticleStatuses } from "../../service/article";
import { requireUser, delCache } from "#server/utils/context";
const updateSchema = z.object({
title: z.string().min(1, "标题不能为空").max(255, "标题不能超过 255 字").optional(),
content: z.string().min(1, "内容不能为空").optional(),
summary: z.string().max(500, "摘要不能超过 500 字").nullable().optional(),
cover: z.string().max(500).nullable().optional(),
status: z.enum(ArticleStatuses).optional(),
cardIds: z
.array(
z.object({
cardId: z.number().int().positive("无效的卡片 ID"),
sortOrder: z.number().int().optional(),
}),
)
.nullable()
.optional(),
});
export default defineWrappedResponseHandler(async (event) => {
await requireUser(event);
const idParam = getRouterParam(event, "id");
if (!idParam) return R.throwError(400, "缺少文章 ID", null);
const id = parseInt(idParam);
if (isNaN(id)) return R.throwError(400, "文章 ID 格式不正确", null);
const existing = await getArticleById(id);
if (!existing) return R.throwError(404, "文章不存在", null);
const body = await readBody(event);
const data = validate(updateSchema, body);
const updated = await updateArticle(id, data);
if (!updated) return R.throwError(500, "更新失败", null);
// Clear card caches for both old and new card associations
const oldCardIds = new Set(existing.cards.map((c) => c.id));
const newCardIds = new Set(updated.cards.map((c) => c.id));
const affectedCardIds = new Set([...oldCardIds, ...newCardIds]);
if (affectedCardIds.size > 0) {
await Promise.all([...affectedCardIds].map((cid) => delCache(`card:${cid}`)));
}
return R.success(updated);
});